package com.ld.control.business.equipment.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ld.control.business.equipment.mapper.EquipmentDataFieldConfigMapper;
import com.ld.control.business.equipment.mapper.EquipmentMapper;
import com.ld.control.business.equipment.mapper.EquipmentMethodTmpMapper;
import com.ld.control.business.equipment.model.EquipmentDataFieldConfigModel;
import com.ld.control.business.equipment.model.EquipmentMethodTmpModel;
import com.ld.control.business.equipment.model.EquipmentModel;
import com.ld.control.business.equipment.service.EquipmentService;
import com.ld.control.business.equipment.vo.external.EquipmentCommandSendParamReqVo;
import com.ld.control.business.equipment.vo.req.EquipmentReqVo;
import com.ld.control.business.equipment.vo.resp.EquipmentDataFieldConfigRespVo;
import com.ld.control.business.equipment.vo.resp.EquipmentRespVo;
import com.ld.control.business.equipment.vo.resp.EquipmentSampleFieldShowRespVo;
import com.ld.control.business.region.service.RegionService;
import com.ld.control.common.vo.EquipmentStatusInfo;
import com.ld.control.common.vo.GenerateListVo;
import com.ld.control.common.vo.GeneratePageListVo;
import com.ld.control.properties.LDProperties;
import com.ld.control.sysenum.DeleteFlagEnum;
import com.ld.control.sysenum.EquipmentStatusEnum;
import com.ld.control.utils.HttpUtils;
import com.ld.control.utils.JWTUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>
 * 设备表 服务实现类
 * </p>
 *
 * @author wangfeng
 * @since 2024-04-17
 */
@Slf4j
@Service
public class EquipmentServiceImpl extends ServiceImpl<EquipmentMapper, EquipmentModel> implements EquipmentService {

    @Autowired
    private EquipmentMapper equipmentMapper;

    @Autowired
    private EquipmentMethodTmpMapper equipmentMethodTmpMapper;

    @Autowired
    private JWTUtils jwtUtils;

    @Autowired
    private RegionService regionService;

    @Autowired
    private LDProperties ldProperties;

    @Autowired
    private EquipmentDataFieldConfigMapper equipmentDataFieldConfigMapper;

    @Override
    public void add(EquipmentReqVo reqVo) {
        Long currentUserAccountId = jwtUtils.getCurrentUserAccountId();
        EquipmentModel equipmentModel = new EquipmentModel();
        BeanUtils.copyProperties(reqVo, equipmentModel);
        equipmentModel.setDelFlag(DeleteFlagEnum.NO.getCode());
        equipmentModel.setStatus(EquipmentStatusEnum.OFF_LINE.getStatus());
        equipmentModel.setCreateBy(currentUserAccountId);
        equipmentModel.setCreateTime(new Date());
        equipmentMapper.insert(equipmentModel);
    }

    @Override
    public void update(EquipmentReqVo reqVo) {
        Long currentUserAccountId = jwtUtils.getCurrentUserAccountId();
        EquipmentModel equipmentModel = new EquipmentModel();
        BeanUtils.copyProperties(reqVo, equipmentModel);
        equipmentModel.setUpdateBy(currentUserAccountId);
        equipmentModel.setUpdateTime(new Date());
        equipmentMapper.updateById(equipmentModel);
    }

    @Override
    public void deleteById(Long id) {
        equipmentMapper.updateDelFlagById(id);
    }

    @Override
    public EquipmentRespVo getById(Long id) {
        EquipmentRespVo respVo = new EquipmentRespVo();
        EquipmentModel equipmentModel = equipmentMapper.selectById(id);
        BeanUtils.copyProperties(equipmentModel, respVo);
        return respVo;
    }

    @Override
    public GeneratePageListVo<EquipmentRespVo> getPageList(Long regionId, String name, String code, Integer status, Integer useFlag, Integer current, Integer size) {
        Map<Long, String> nameMap = regionService.getNameMap();
        IPage<EquipmentRespVo> iPage = new Page<>(current, size);
        IPage<EquipmentRespVo> iPageList = equipmentMapper.selectPageList(iPage, regionId, name, code, status, useFlag);
        for (EquipmentRespVo equipmentRespVo : iPageList.getRecords()) {
            equipmentRespVo.setRegionName(nameMap.get(equipmentRespVo.getRegionId()));
        }
        return new GeneratePageListVo<>(iPageList);
    }

    @Override
    public EquipmentRespVo getByMethodTmpId(Long methodTmpId) {
        EquipmentRespVo respVo = new EquipmentRespVo();
        EquipmentMethodTmpModel equipmentMethodTmpModel = equipmentMethodTmpMapper.selectById(methodTmpId);
        EquipmentModel equipmentModel = equipmentMapper.selectById(equipmentMethodTmpModel.getEquipmentId());
        BeanUtils.copyProperties(equipmentModel, respVo);
        return respVo;
    }

    @Override
    public void backgroundUpdateEquipmentStatus() {
        QueryWrapper<EquipmentModel> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(EquipmentModel.DEL_FLAG, DeleteFlagEnum.NO.getCode());
        queryWrapper.eq(EquipmentModel.USE_FLAG, 1);
        List<EquipmentModel> equipmentModelList = equipmentMapper.selectList(queryWrapper);
        EquipmentModel equipmentUpdate = null;
        for (EquipmentModel equipmentModel : equipmentModelList) {
            equipmentUpdate = new EquipmentModel();
            Integer equipmentStatus = getEquipmentStatus(equipmentModel);
            equipmentUpdate.setId(equipmentModel.getId());
            equipmentUpdate.setStatus(equipmentStatus);
            equipmentUpdate.setUpdateTime(new Date());
            equipmentMapper.updateById(equipmentUpdate);
        }
    }

    @Override
    public void updateStatus(Long id, Integer status) {
        EquipmentModel equipmentModel = equipmentMapper.selectById(id);
        equipmentModel.setId(id);
        equipmentModel.setStatus(status);
        equipmentModel.setUpdateTime(new Date());
        equipmentMapper.updateById(equipmentModel);
    }

    @Override
    public void generateMethodEstimatedTime(EquipmentCommandSendParamReqVo sendCommandParams) {
        long currentTime = System.currentTimeMillis();
        Long sendTime = sendCommandParams.getSendTime();
        long estimatedTime = (currentTime - sendTime) / 1000;
        EquipmentMethodTmpModel equipmentMethodTmpModel = equipmentMethodTmpMapper.selectById(sendCommandParams.getMethodTmpId());
        equipmentMethodTmpModel.setEstimatedTime((int)estimatedTime);
        equipmentMethodTmpModel.setUpdateTime(new Date());
        equipmentMethodTmpMapper.updateById(equipmentMethodTmpModel);
    }

    @Override
    public List<EquipmentRespVo> getRunMethodEquipment(Long taskExampleId) {
        return equipmentMapper.selectListByTaskExampleIdRunMethod(taskExampleId);
    }

    @Override
    public Map<Long, EquipmentRespVo> getEquipmentRespVoAllMap() {
        Map<Long, EquipmentRespVo> equipmentRespVoMap = new HashMap<>();
        List<EquipmentRespVo> equipmentRespList = equipmentMapper.selectAllList();
        for (EquipmentRespVo equipmentRespVo : equipmentRespList) {
            equipmentRespVoMap.put(equipmentRespVo.getId(), equipmentRespVo);
        }
        return equipmentRespVoMap;
    }

    @Override
    public List<EquipmentDataFieldConfigRespVo> getEquipmentSampleFieldShowList(Long equipmentId) {
        return equipmentDataFieldConfigMapper.selectListByEquipmentId(equipmentId);
    }

    @Override
    public GenerateListVo<EquipmentRespVo> getAllList() {
        GeneratePageListVo<EquipmentRespVo> pageList = getPageList(null, null, null, null, null, 1, 9999);
        return new GenerateListVo<>(pageList.getList());
    }


    /**
     * 从设备那边获取设备状态
     *
     * @param equipmentModel
     * @return
     */
    public Integer getEquipmentStatus(EquipmentModel equipmentModel) {
        String ip = equipmentModel.getIp();
        Integer port = equipmentModel.getPort();
        String equipmentStatusUrl = ldProperties.getDrive().getEquipmentStatusUrl();
        String sendUrl = "http://" + ip + ":" + port + equipmentStatusUrl + "?equipmentCode=" + equipmentModel.getCode();
        try {
            String respBody = HttpUtils.setGetConnectTimeout(sendUrl, 2L, 2L);
            EquipmentStatusInfo equipmentStatusInfo = JSONObject.parseObject(respBody, EquipmentStatusInfo.class);
            return equipmentStatusInfo.getEquipmentStatus();
        } catch (Exception e) {
            //log.error("syncEquipmentStatus error：{}，equipmentCode：{}", e.getMessage(), equipmentModel.getCode());
            return EquipmentStatusEnum.CONNECTION_FAILED.getStatus();
        }
    }
}
